<template>
  <div
    :class="isZoomIn ? 'bigScreen' : 'minScreen'"
    class="map-box-video"
    draggable="true"
    oncontextmenu="return false"
    @mousedown="handleMouse"
    @mousemove="handleMouse"
    @dblclick.stop
    :id="'mapDrag' + mapIndex"
  >
    <div class="drag" v-drag="(this, that)" v-if="main === 1"></div>
    <div class="top-btn" @dblclick.stop>
      <div class="btn-li" @click="findVideoByCoord(!isOpenFindVideByCoord)">
        <i
          class="iconfont"
          :class="
            isOpenFindVideByCoord
              ? 'icon-shipinzujian_yidizhaoshipin_s'
              : 'icon-shipinzujian_yidizhaoshipin_n'
          "
          c-tip="以地找视频"
          c-tip-placement="bottom"
          c-tip-class="c-tip-normal"
        />
      </div>
      <div @click="openLayerTree()" class="btn-li">
        <i
          class="iconfont"
          :class="
            layerTree
              ? 'icon-shipinzujian_tuceng_s'
              : 'icon-shipinzujian_tuceng_n'
          "
          c-tip="图层树"
          c-tip-placement="bottom"
          c-tip-class="c-tip-normal"
        />
        <el-popover
          ref="layerTree"
          v-model="layerTree"
          :visible-arrow="false"
          placement="bottom-start"
          popper-class="layer-tree-popover"
          trigger="click"
          width="200"
          :append-to-body="false"
        >
          <el-tree
            ref="treeLayer"
            :check-strictly="true"
            :data="layerTreeData"
            :props="defaultProps"
            :show-checkbox="true"
            node-key="key"
            @check-change="checkChange"
            @node-click="handleNodeClick"
            :style="{ 'max-height': treeHeight }"
            @click.stop
          />
        </el-popover>
      </div>
      <div class="btn-li" @click.stop="openViewShedChange(!isOpenViewshed)">
        <i
          class="iconfont"
          :class="
            isOpenViewshed
              ? 'icon-shipinzujian_keshiyukai_s'
              : 'icon-keshiyukai_n'
          "
          c-tip="可视域开关"
          c-tip-placement="bottom"
          c-tip-class="c-tip-normal"
        />
      </div>
      <div class="btn-li" @click.stop="lookAthere(!isOpenLookAtHere)">
        <i
          class="iconfont"
          :class="
            isOpenLookAtHere
              ? 'icon-shipinzujian_kanzheli_s'
              : 'icon-shipinzujian_kanzheli_n'
          "
          c-tip="看这里"
          c-tip-placement="bottom"
          c-tip-class="c-tip-normal"
        />
      </div>
      <div class="btn-li" @click.stop="ranging">
        <i
          class="iconfont"
          :class="
            measureType === 'distance'
              ? 'icon-shipinzujian_icon_ceju_s'
              : 'icon-shipinzujian_icon_ceju_n'
          "
          c-tip="测距"
          c-tip-placement="bottom"
          c-tip-class="c-tip-normal"
        />
      </div>
      <div class="btn-li" @click.stop="areaMeasurement">
        <i
          class="iconfont"
          :class="
            measureType === 'area'
              ? 'icon-shipinzujian_cemian_s'
              : 'icon-shipinzujian_cemian_n'
          "
          c-tip="测面"
          c-tip-placement="bottom"
          c-tip-class="c-tip-normal"
        />
      </div>
      <div class="btn-li" @click.stop="lnglatLocationShow()">
        <i
          class="iconfont"
          :class="
            lnglatLocation.show
              ? 'icon-shipinzujian_jingweidudingwei_s'
              : 'icon-jingweidudingwei_n'
          "
          c-tip="经纬度定位"
          c-tip-placement="bottom"
          c-tip-class="c-tip-normal"
        />
      </div>
      <div class="btn-li" @click.stop="clearLayer(false)">
        <i
          class="iconfont icon-shipinzujian_qingchu_n"
          c-tip="清除"
          c-tip-placement="bottom"
          c-tip-class="c-tip-normal"
        />
      </div>
      <div
        v-if="lnglatLocation.show"
        class="lnglat-location"
        :class="{ large: lnglatLocation.type !== 1 }"
        :style="{ 'max-height': treeHeight }"
        @click.stop
      >
        <div class="ttag">
          <div
            class="radio"
            :class="{ on: lnglatLocation.type === 1 }"
            @click="chooseLnglatLocationType(1)"
          >
            <b /><span>点</span>
          </div>
          <div
            class="radio"
            :class="{ on: lnglatLocation.type === 2 }"
            @click="chooseLnglatLocationType(2)"
          >
            <b /><span>线</span>
          </div>
          <div
            class="radio"
            :class="{ on: lnglatLocation.type === 3 }"
            @click="chooseLnglatLocationType(3)"
          >
            <b /><span>面</span>
          </div>
          <i
            class="iconfont icon-shijianxiangqingzhankai lnglatLocation-down"
            :class="{ down: lnglatLocation.down }"
            @click="lnglatLocation.down = !lnglatLocation.down"
          />
        </div>
        <template v-if="lnglatLocation.type && lnglatLocation.down">
          <div class="ccon">
            <div
              class="it"
              v-for="(item, index) in lnglatLocation.points"
              :key="index"
            >
              <span>经度</span>
              <div class="input" :class="{ error: item.lngError }">
                <input
                  type="text"
                  v-model="item.lng"
                  placeholder="输入经度"
                  @input="lnglatLocationInput(index, 'lng')"
                />
              </div>
              <span>纬度</span>
              <div class="input" :class="{ error: item.latError }">
                <input
                  type="text"
                  v-model="item.lat"
                  placeholder="输入纬度"
                  @input="lnglatLocationInput(index, 'lat')"
                />
              </div>
              <template v-if="lnglatLocation.type !== 1">
                <i
                  class="iconfont icon-tongyong_icon_biaogexinzeng"
                  :class="{ unable: lnglatLocation.points.length >= 5 }"
                  @click="addRow(1, index)"
                ></i>
                <i
                  class="iconfont icon-tongyong_icon_biaogeshanchu1"
                  :class="{
                    unable: lnglatLocation.points.length <= lnglatLocation.type,
                  }"
                  @click="addRow(-1, index)"
                ></i>
              </template>
            </div>
          </div>
          <div v-if="isLnglatLocationInputError()" class="tts">
            <span>经度范围为-180到180，最多6位小数；</span>
            <span>纬度范围为-90到90，最多6位小数。</span>
          </div>
          <div class="bbtn">
            <span class="on" @click="lnglatLocationOk()">确定</span>
            <span @click="lnglatLocationClear()">清除</span>
          </div>
        </template>
      </div>
    </div>
    <div v-if="main === 1 && mapLevel" class="map-level">
      <span>{{ mapLevel }}</span>
      <i
        class="iconfont icon-tongyong-ditufangda"
        :class="{ unable: +mapLevel >= 18 }"
        @click.stop="changeMapLevel(1)"
      />
      <i
        class="iconfont icon-tongyong-ditusuoxiao"
        :class="{ unable: +mapLevel <= 5 }"
        @click.stop="changeMapLevel(-1)"
      />
    </div>
    <div class="right-btn" @dblclick.stop>
      <div v-if="main !== 1 && mapLevel" class="map-level">
        <span>{{ mapLevel }}</span>
        <i
          class="iconfont icon-tongyong-ditufangda"
          :class="{ unable: +mapLevel >= 18 }"
          @click.stop="changeMapLevel(1)"
        />
        <i
          class="iconfont icon-tongyong-ditusuoxiao"
          :class="{ unable: +mapLevel <= 5 }"
          @click.stop="changeMapLevel(-1)"
        />
      </div>
      <div class="rbtn-li">
        <div
          c-tip="窗口切换"
          c-tip-placement="right"
          c-tip-class="c-tip-normal"
          class="qie-huan"
          @click="handleQieHuan"
        >
          <i class="iconfont icon-qiujichuangkouqiehuan" />
        </div>
      </div>
      <div
        v-if="main === 1"
        :c-tip="!isZoomIn ? '放大' : '缩小'"
        c-tip-placement="right"
        c-tip-class="c-tip-normal"
        class="rbtn-li"
        @click="handleBoxZoomClick()"
      >
        <i
          :class="!isZoomIn ? 'icon-fangda2' : 'icon-AR-suoxiao'"
          class="iconfont"
        />
      </div>
      <div
        c-tip="定位到摄像机"
        c-tip-placement="right"
        c-tip-class="c-tip-normal"
        class="rbtn-li"
        @click="locateToCamera"
      >
        <i class="iconfont icon-shexiangjidingwei" />
      </div>
      <div
        :c-tip="mapType === 'satellite' ? '切换到影像地图' : '切换到卫星地图'"
        c-tip-placement="right"
        c-tip-class="c-tip-normal"
        class="rbtn-li"
        @click="mapTypeChange"
      >
        <i
          class="iconfont"
          :class="mapType === 'satellite' ? 'icon-a-weixing1' : 'icon-ditu'"
        />
      </div>
      <div
        v-if="main === 1"
        c-tip="退出"
        c-tip-placement="right"
        c-tip-class="c-tip-normal"
        class="rbtn-li"
        @click="out()"
      >
        <i class="iconfont icon-tuichuhuifang item" />
      </div>
    </div>
    <div
      :id="'mapToVideoBox' + mapIndex"
      class="map-content"
      ondragstart="return false"
    />
    <div
      v-for="item in measureTipList"
      :id="'measureTip-' + item.key"
      :key="item.key"
      class="measure-over-tip"
    >
      {{ item.value }}
    </div>
    <Ts ref="ts" class="ts" />
  </div>
</template>

<script>
import {
  addMarker,
  clearCircle,
  clearPolyline,
  closeInfoWindow,
  clusterSetViewshed,
  describingCircle2,
  describingPolyline,
  getPolygonCenter,
  initCTMap,
  measureClass,
  setZoomAndCenter,
  showMarkCluster,
  showTextPolygonId,
} from "@/utils/openLayerCommon";
import { queryDeviceForWE } from "@/api/alarmEvent/mapHome.js";
import {
  getXjxlFeaturesByIds,
  pointsValid,
  turnToPtzByPointAngle,
} from "@/api/video/video";
import { measureOverlayClass, pointClass } from "./mapToVideo";
import { getDeviceVisibleBySite } from "@/api/video/index.js";
import { getTenantLayerList } from "@/api/spotPlotting";
import { getPercentPtzByMassPointBatch } from "@/api/video/videoPTZ.js";
import CTMapOl from "@ct/ct_map_ol";
import "@ct/ct_map_ol/index.css";
import lookPointPng from "@/assets/image/lookPointPng.png";

import arOnline_g from "@/assets/image/ar/ar-online-g.png";
import arOnline from "@/assets/image/ar/ar-online.png";
import arOffline_g from "@/assets/image/ar/ar-outline-g.png";
import arOffline from "@/assets/image/ar/ar-outline.png";
import ipcOnline_g from "@/assets/image/ar/ipc-online-g.png";
import ipcOnline from "@/assets/image/ar/ipc-online.png";
import ipcOffline_g from "@/assets/image/ar/ipc-outline-g.png";
import ipcOffline from "@/assets/image/ar/ipc-outline.png";
import point from "@/assets/image/video/point.png";
import Ts from "@/components/canvas/ts.vue";
import CommonMap from "@/utils/CommonMap";
import request from "@/utils/request";
import { transCoordinate } from "@/utils/CommonCtMapOl";

let measure = null;
let draw = null;
let drawVectorSource = null;
let drawVectorLayer = null;
let doubleClickZoom = new CTMapOl.interaction.DoubleClickZoom();
let doubleClickZoomArr = null;
let treeLayer = null;
// 可视域轮询
let visibleInterval = null;
// 视频测距测面显示到地图上
let measureOverlay = null;
// 看这里实例
let lookPoint = null;
export default {
  name: "mapToVideo",
  components: { Ts },
  props: {
    longitude: {
      //经度
      type: [String, Number],
    },
    latitude: {
      //纬度
      type: [String, Number],
    },
    deviceCode: {
      type: [String, Number],
      required: true,
    },
    channelCode: {
      type: [String, Number],
      required: true,
    },
    // 分屏传入this
    vueIns: {
      type: Object,
      default: () => {
        return {};
      },
    },
    main: {}, //视图联动主屏, 1: 视频, 2: 地图
    isZoomIn: {}, //视图联动辅窗放大缩小
    layerId: {},
    freckleId: {},
  },
  data() {
    return {
      mapIndex: "",
      // 是否打开以视频找地
      isOpenFindVideByCoord: false,
      // 是否打开可视域
      isOpenViewshed: true,
      isOpenLookAtHere: false,
      // 测量类型（距离distance或者面积area）
      measureType: "",
      // 地图类型 wx 卫星
      mapType: "satellite",
      // currentNodeKey: ['1-1'],
      // 图层数据
      layerTree: false, //图层下拉框
      layerTreeData: [],
      defaultProps: {
        children: "children",
        label: "label",
      },
      measureTipList: [],
      selectLayer: {
        key: "",
        data: "",
      },
      selectPolygonLayer: null,
      industryType: "", //行业编码
      viewDistanceColor: "rgba(58, 160, 255, 0.3)", // 可视域颜色
      viewAngleColor: "rgba(58, 160, 255, 0.7)", // 可视域角度颜色
      deviceIcon: null,
      isArCamera: false,
      isEnableDraw: false,
      tipMsg: [],
      that: this,
      treeHeight: "120px",
      flag: true,
      LayeredClusterViewShed: null,
      mapRef: null,
      globalMap: null,
      abbreviation: "yjjbnt", // 地图类型
      measureClearOneFlag: false, //判断测距测面功能右键撤销和标绘完成后点击×撤销
      mapLevel: "", //地图层级
      lnglatLocation: {
        //经纬度定位
        show: false, //显示
        down: true, //经纬度定位展开
        type: false, //点线面选择, 1: 点, 2: 线, 3: 面
        points: [], //点位列表
        cover: [], //地图覆盖物
      },
      oldDrawLayer: [],
    };
  },
  watch: {
    /**
     * 打开经纬度定位功能最大化
     */
    isLnglatLocation(b) {
      if (b) {
        this.handleBoxZoomClick(true);
      }
    },
  },
  computed: {
    userId() {
      return this.$store.getters.userInfo.userId;
    },
    isTenant() {
      return Object.keys(this.vueIns).length === 0
        ? this.$store.getters.userInfo.tenantId
        : this.vueIns.$store.getters.userInfo.tenantId;
    },
    /**
     * 打开经纬度定位功能最大化
     */
    isLnglatLocation() {
      return this.lnglatLocation.show && this.main === 1;
    },
    /**
     * 经纬度定位录入错误
     */
    isLnglatLocationInputError() {
      const points = this.lnglatLocation.points;
      return function (submit) {
        const errors = points.filter((item) => {
          if (submit) {
            if (!item.lng) {
              item.lngError = true;
            }
            if (!item.lat) {
              item.latError = true;
            }
          }
          return item.lngError || item.latError;
        });
        return errors.length;
      };
    },
  },
  created() {
    this.mapIndex = this.UUID();
    if (Object.keys(this.vueIns).length) {
      this.$store = this.vueIns.$store;
    }
  },
  mounted() {
    this.industryType = this.$store.getters.industry.split(" ");
    if (this.industryType.includes("g")) {
      this.viewDistanceColor = "rgba(255, 245, 54, 0.2)"; //可视域颜色
      this.viewAngleColor = "rgba(255, 245, 54, 0.7)"; //可视域角度颜色
    }
    this.resizeObserver = new ResizeObserver(() => {
      this.computeHeight();
    });
    this.resizeObserver.observe(this.$el);
    this.queryDeviceData();
  },
  directives: {
    drag: {
      // 指令的定义
      bind: function (el, binding) {
        /* 拖动 */
        el.onmousedown = (e) => {
          e.stopPropagation();
          let _mapDrag = $("#mapDrag" + binding.value.that.mapIndex);
          binding.value.that.flag = false;
          const pw = _mapDrag.parent().outerWidth();
          const ow = _mapDrag.outerWidth();
          document.onmousemove = (mousemoveEvent) => {
            if (binding.value.that.main === 2) {
              return false;
            }
            const wp = ((ow + e.clientX - mousemoveEvent.clientX) / pw) * 100;
            if (wp >= 50) {
              binding.value.that.$emit("update:isZoomIn", true);
            } else {
              binding.value.that.$emit("update:isZoomIn", false);
            }
            _mapDrag.css({
              width: wp + "%",
              height: wp + "%",
            });
          };
          document.onmouseup = () => {
            document.onmousemove = null;
            document.onmouseup = null;
            binding.value.that.flag = true;
          };
        };
      },
    },
  },
  methods: {
    /**
     * 经纬度定位录入
     */
    lnglatLocationInput(index, key) {
      const item = this.lnglatLocation.points[index];
      item[key + "Error"] = "";
      let it = item[key];
      if (!it) {
        item[key + "Old"] = it;
        return false;
      }
      if (isNaN(Number(it)) && it !== "-") {
        item[key] = item[key + "Old"] || "";
      } else {
        it = it.replace(/ /g, "");
        const decimal = it.split(".")[1] || "";
        if (decimal.length > 6) {
          it = it.substring(0, it.length - (decimal.length - 6));
        }
        item[key] = item[key + "Old"] = it;
      }
      if (key === "lng" && (Number(it) < -180 || Number(it) > 180)) {
        item[key + "Error"] = true;
      }
      if (key === "lat" && (Number(it) < -90 || Number(it) > 90)) {
        item[key + "Error"] = true;
      }
    },
    /**
     * 打开经纬度定位
     */
    lnglatLocationShow(show = !this.lnglatLocation.show) {
      this.lnglatLocationClear();
      Object.assign(this.lnglatLocation, this.$options.data().lnglatLocation);
      this.lnglatLocation.show = show;
      if (show) {
        this.chooseLnglatLocationType();
      }
    },
    /**
     * 经纬度定位选择点线面
     */
    chooseLnglatLocationType(type = 1) {
      this.lnglatLocationClear();
      this.lnglatLocation.type = type;
      this.lnglatLocation.points = [];
      for (let i = 0; i < type; i++) {
        this.addRow(1, i - 1);
      }
    },
    /**
     * 经纬度定位 增加一行
     */
    addRow(flag, index) {
      if (flag > 0) {
        if (this.lnglatLocation.points.length >= 5) {
          return false;
        }
        this.lnglatLocation.points.splice(index + 1, 0, {
          lng: "",
          lat: "",
          lngError: "",
          latError: "",
        });
      } else {
        if (this.lnglatLocation.points.length <= this.lnglatLocation.type) {
          return false;
        }
        this.lnglatLocation.points.splice(index, 1);
      }
    },
    /**
     * 经纬度定位确认
     */
    lnglatLocationOk() {
      if (this.isLnglatLocationInputError(true)) {
        return false;
      }
      this.lnglatLocationClear(true);
      let { type, points } = this.lnglatLocation;
      points = points.map((item) => {
        return [Number(item.lng), Number(item.lat)];
      });
      if (
        points.length > 2 &&
        points[0][0] === points[points.length - 1][0] &&
        points[0][1] === points[points.length - 1][1]
      ) {
        points.pop();
      }
      const center = getPolygonCenter(points);
      if (type === 1) {
        const [lng, lat] = points[0];
        const marker = addMarker(this.mapRef, lng, lat, "666", {
          imgPath: point,
          offset: [-20, -40],
          imgWidth: 40,
          imgHeight: 40,
        });
        this.lnglatLocation.cover.push(marker);
      }
      if (type === 2) {
        measureOverlay.drawLine(points, "line2");
      }
      if (type === 3) {
        measureOverlay.drawArea([points], "ploygon2");
      }
      this.fitPathToScreen(points);
      this.turnCamera(center);
      this.lnglatLocation.down = false;
    },
    /**
     * 经纬度定位清除
     */
    lnglatLocationClear(cover) {
      if (!cover) {
        this.lnglatLocation.points.forEach((item) => {
          Object.keys(item).forEach((key) => {
            item[key] = "";
          });
        });
      }
      this.lnglatLocation.cover.forEach((item) => {
        try {
          closeInfoWindow(this.mapRef, item);
        } catch (e) {
          //console.log(e)
        }
      });
      this.lnglatLocation.cover = [];
      try {
        measureOverlay.removeByKey("line2");
      } catch (e) {
        //console.log(e)
      }
      try {
        measureOverlay.removeByKey("ploygon2");
      } catch (e) {
        //console.log(e)
      }
    },
    /**
     * 退出视频联动
     */
    out() {
      this.closeVisibleInterval();
      this.$emit("out");
    },
    handleMouse(event) {
      if (this.flag) {
        event.stopPropagation();
      }
    },
    /**
     * 传值给地图
     * @param type 1:以地找视频 2:测距 3:测面 4:清除标绘(1、2、3) 5:电子围栏选中 6视频按钮的清除, 99: 提示信息
     * @param layerId 选中图层id
     * @param freckleId 选中图斑id
     * @param vertexLngLatList [{ longitude: "111.111111", latitude: "33.333333" }] 顶点经纬度坐标
     */
    videoToMap({
      type,
      layerId,
      freckleId,
      vertexLngLatList,
      geometry,
      tbbh,
      text,
    }) {
      console.log("视频传过来的数据", {
        type,
        layerId,
        freckleId,
        vertexLngLatList,
        geometry,
        tbbh,
        text,
      });
      if (type === 99) {
        this.$refs["ts"]?.doMessTs(text, true);
      }
      this.measureTipList = [];
      if (type === 1) {
        // 以地找视频
        let path = vertexLngLatList.map((item) => [
          Number(item.longitude),
          Number(item.latitude),
        ]);
        // setZoomAndCenter(this.mapRef, path[0][0], path[0][1], 12);
        measureOverlay.drawArea([path], "videomap", true);
        this.fitPathToScreen(path);
      }
      if (type === 2) {
        // 测距
        let path = vertexLngLatList.map((item) => [
          Number(item.longitude),
          Number(item.latitude),
        ]);
        // setZoomAndCenter(this.mapRef, path[0][0], path[0][1], 12);
        measureOverlay.drawLine(path, "line1");
        this.fitPathToScreen(path);
      }
      if (type === 3) {
        // 测面
        let path = vertexLngLatList.map((item) => [
          Number(item.longitude),
          Number(item.latitude),
        ]);
        // setZoomAndCenter(this.mapRef, path[0][0], path[0][1], 12);
        measureOverlay.drawArea([path], "ploygon1");
        this.fitPathToScreen(path);
      }
      if (type === 4) {
        this.clearLayer(true);
      }
      if (type === 5) {
        console.log("videoToMap type === 5", {
          type,
          layerId,
          freckleId,
          vertexLngLatList,
          geometry,
          tbbh,
          text,
        });
        // 电子围栏选中
        closeInfoWindow(
          this.mapRef,
          this.mapRef.getOverlayById("infoWindowId")
        );
        if (this.selectLayer.key === layerId) {
          this.selectFeatureById(layerId, freckleId, (resp) => {
            const geoData = resp.data.geoData;
            let center = CTMapOl.turf.center(geoData);
            center = center.geometry.coordinates;
            setTimeout(() => {
              if (geoData.features) {
                this.HighlightPolygon(geoData);
                this.showNumber(geoData);
                setZoomAndCenter(this.mapRef, center[0], center[1], 15);
              }
            });
          });
        } else {
          this.clearCover();
          this.removeNumber();
        }
      }
      if (type === 6) {
        if (this.isOpenFindVideByCoord) {
          this.findVideoByCoordHandle(!this.isOpenFindVideByCoord);
        }
        if (this.measureType === "distance") {
          this.ranging();
        }
        if (this.measureType === "area") {
          this.areaMeasurement();
        }
      }
    },
    /**
     * 将path放在屏幕中
     */
    fitPathToScreen(path, onlyPath) {
      if (!onlyPath) {
        path.push([Number(this.longitude), Number(this.latitude)]);
      }
      const geom = new CTMapOl.geom.Polygon([path]);
      geom.transform("EPSG:4326", "EPSG:3857");
      this.mapRef.getView().fit(geom, {
        padding: [80, 50, 50, 50],
      }); //设置地图的缩放距离离屏幕的大小
    },
    async queryDeviceData() {
      try {
        let params = {
          deviceCode: this.deviceCode,
        };
        let res = await queryDeviceForWE(params);
        if (res.code === 200) {
          this.getDeivceIcon(res.data);
          console.log("设备信息", res.data);
        }
      } catch (err) {
        console.log(error);
      }
      this.initmap();
    },

    initmap() {
      console.log("initmap");
      this.mapId = `mapToVideoBox${this.mapIndex}`;
      let { map, mapMap } = initCTMap(this.mapId);
      this.globalMap = mapMap;
      this.mapRef = map;
      CommonMap.setMap(map, this.mapId);
      CommonMap.setMapInstance(mapMap, this.mapId);
      this.getDeviceVisibleBySite(() => {
        if (!(this.layerId && this.freckleId)) {
          this.locateToCamera();
        }
      });
      this.openVisibleInterval();
      this.initDrawLayer();
      // 测距
      measure = new measureClass(
        this.mapRef,
        "undo",
        this.measureOnFinish.bind(this),
        true,
        "rgba(237, 81, 88, 1)",
        this.measureOnRemove.bind(this),
        this.measureOnReduce.bind(this)
      );
      measureOverlay = new measureOverlayClass(this.mapRef, drawVectorSource);
      this.mapRef.on("click", this.mapClickGetPolygon);
      this.mapRef.on("click", this.mapClickFn.bind(this));
      this.initTenantLayerList();
      this.showMapLevel();
    },
    /**
     * 显示地图层级
     */
    showMapLevel() {
      this.mapLevel = this.mapRef.getView().getZoom();
      this.mapRef.on("moveend", () => {
        this.mapLevel = this.mapRef.getView().getZoom();
      });
    },
    /**
     * 控制地图层级加减
     */
    changeMapLevel(num) {
      if (num > 0) {
        CTMapOl.api.fixZoomin(this.mapRef);
      } else {
        CTMapOl.api.fixZoomout(this.mapRef);
      }
    },
    initShedLayer(targetVal, successFn) {
      showMarkCluster(
        this.mapRef,
        {
          list: [
            {
              id: this.deviceCode,
              longitude: this.longitude,
              latitude: this.latitude,
              distance: 0, // 半径，单位 米
              heading: 0, // 朝向，顺时针旋转
              angle: targetVal.horizRange || (this.isArCamera ? 180.01 : 50.01), // 角度范围
              isWarning: false, // 是否报警状态
              iconSize: [30, 30],
              icon: this.deviceIcon,
              clickIcon: this.deviceIcon,
              offset: [15, 15],
            },
          ],
          clusterImgItem: {
            viewDistanceColor: this.viewDistanceColor,
            viewAngleColor: this.viewAngleColor,
            keepPartialViewShed: true,
          },
        },
        null,
        null,
        (LayeredClusterViewShed) => {
          this.LayeredClusterViewShed = LayeredClusterViewShed;
          if (!(this.layerId && this.freckleId)) {
            this.LayeredClusterViewShed.locationById({ id: this.deviceCode });
          }
          this.clusterSetViewshed(targetVal);
          if (successFn) {
            successFn();
          }
        }
      );
    },
    /**
     * 轮询获取点位可视域
     */
    getDeviceVisibleBySite(successFn) {
      getDeviceVisibleBySite({ deviceCodes: [this.deviceCode] }).then((res) => {
        if (res.code === 200 && res.data.length > 0) {
          let targetVal = res.data[0];
          if (this.LayeredClusterViewShed) {
            this.clusterSetViewshed(targetVal);
          } else {
            this.initShedLayer(targetVal, successFn);
          }
        }
        //处理摄像机无可视域情况，直接打点
        if (res.code === 200 && res.data.length === 0) {
          showMarkCluster(
            this.mapRef,
            {
              list: [
                {
                  id: this.deviceCode,
                  longitude: this.longitude,
                  latitude: this.latitude,
                  distance: 0, // 半径，单位 米
                  heading: 0, // 朝向，顺时针旋转
                  // angle: targetVal.horizRange || (this.isArCamera ? 180.01 : 50.01), // 角度范围
                  isWarning: false, // 是否报警状态
                  iconSize: [30, 30],
                  icon: this.deviceIcon,
                  clickIcon: this.deviceIcon,
                  offset: [15, 15],
                },
              ],
              clusterImgItem: {
                viewDistanceColor: this.viewDistanceColor,
                viewAngleColor: this.viewAngleColor,
                keepPartialViewShed: true,
              },
            },
            null,
            null,
            (LayeredClusterViewShed) => {
              this.LayeredClusterViewShed = LayeredClusterViewShed;
              if (successFn) {
                successFn();
              }
            }
          );
        }
      });
    },
    clusterSetViewshed(targetVal) {
      clusterSetViewshed(this.LayeredClusterViewShed, {
        idKey: "id",
        idValue: this.deviceCode,
        guid: this.deviceCode,
        longitude: this.longitude,
        latitude: this.latitude,
        distance: Number(targetVal?.visualRange || 3) * 1000,
        heading: Number(targetVal?.horizViewRange || "157.79"),
        angle: targetVal.horizRange || (this.isArCamera ? 180.01 : 50.01),
        ishalf: this.isArCamera ? 1 : 0,
        viewDistanceColor: this.viewDistanceColor,
        viewAngleColor: this.viewAngleColor,
      });
    },
    openVisibleInterval() {
      this.closeVisibleInterval();
      visibleInterval = setInterval(() => {
        this.getDeviceVisibleBySite();
      }, 5000);
    },
    closeVisibleInterval() {
      clearInterval(visibleInterval);
      visibleInterval = null;
    },
    /**
     * 初始化绘制图层
     */
    initDrawLayer() {
      // 绘制图层
      const drawStyle = new CTMapOl.style.Style({
        fill: new CTMapOl.style.Fill({
          color: "rgba(223, 34, 24, 0.3)",
        }),
        stroke: new CTMapOl.style.Stroke({
          color: "rgba(223, 34, 24, 0.8)",
          width: 2,
        }),
      });
      drawVectorSource = new CTMapOl.source.Vector({ wrapX: false });
      drawVectorLayer = new CTMapOl.layer.Vector({
        source: drawVectorSource,
        zIndex: Infinity,
        style: drawStyle,
      });
      this.mapRef.addLayer(drawVectorLayer);

      doubleClickZoomArr = this.mapRef
        .getInteractions()
        .array_.filter(
          (item) => item.constructor.name === doubleClickZoom.constructor.name
        );

      draw = new CTMapOl.interaction.Draw({
        source: drawVectorSource,
        type: "Polygon",
        style: {
          "stroke-color": "rgba(223, 34, 24, 0.8)",
          "stroke-width": 2,
          "fill-color": "rgba(223, 34, 24, 0.3)",
        },
      });
    },
    /**
     * 初始化租户图层列表
     */
    initTenantLayerList() {
      getTenantLayerList({}).then((res) => {
        if (res.code === 200) {
          this.createTreeLayerData(res.data);
        }
      });
    },
    createTreeLayerData(baseTreeData) {
      let treeData = [];
      const defaultLayer = [];
      baseTreeData.forEach((item, index) => {
        let children = item.layers.map((layer, i) => {
          layer["key"] = layer.id;
          layer["label"] = layer.customName;
          layer["isLeaf"] = true;
          if (this.layerId === layer.id) {
            defaultLayer.push(i);
          }
          return layer;
        });
        let obj = {
          label: item.layerTypeName,
          key: index,
          disable: true,
          children,
        };
        if (defaultLayer.length === 1) {
          defaultLayer.unshift(index);
        }
        treeData.push(obj);
      });
      if (this.layerId && this.freckleId) {
        this.autoSelect = [this.layerId, this.freckleId];
      }
      this.layerTreeData = treeData;
      this.$nextTick(() => {
        if (treeData.length > 0 && this.$refs.treeLayer) {
          // 默认选中
          let defaultSelect =
            treeData[defaultLayer[0] || 0].children[defaultLayer[1] || 0];
          this.$refs.treeLayer.setCheckedKeys([]);
          this.$refs.treeLayer.setCheckedKeys([defaultSelect.key]);
          this.sendMapToVideo(defaultSelect.key, defaultSelect);
          this.checkChange();
        }
      });
    },
    /**
     * 图层树点击事件
     */
    handleNodeClick(data) {
      if (!data.isLeaf) {
        return;
      }
      let selectCheckNode = this.$refs.treeLayer.getCheckedNodes();
      if (selectCheckNode && selectCheckNode.length === 1) {
        if (selectCheckNode[0].key === data.key) {
          this.$refs.treeLayer.setCheckedKeys([]);
          this.sendMapToVideo("", {});
        } else {
          this.$refs.treeLayer.setCheckedKeys([]);
          this.$refs.treeLayer.setCheckedKeys([data.key]);
          this.sendMapToVideo(data.key, data, true);
        }
      } else {
        this.$refs.treeLayer.setCheckedKeys([data.key]);
        this.sendMapToVideo(data.key, data, true);
      }
    },
    sendMapToVideo(selectLayerKey, layerData) {
      this.abbreviation = layerData.abbreviation;
      this.selectLayer = {
        key: selectLayerKey,
        data: layerData,
      };

      this.$emit("mapToVideo", {
        type: 4,
        layerId: this.selectLayer.key,
        layerData: this.selectLayer.data,
      });

      setTimeout(() => {
        if (this.autoSelect) {
          const freckleId = this.autoSelect[1];
          this.selectFeatureById(this.autoSelect[0], freckleId, (resp) => {
            const geoData = resp.data.geoData;
            let geometry = geoData.features[0].geometry;
            let properties = geoData.features[0].properties;
            if (geoData.features) {
              let path = geometry.coordinates[0][0];
              console.log(path);
              this.HighlightPolygon(geoData);
              this.showNumber(geoData);
              this.fitPathToScreen(path, true);
            }
            this.$emit("mapToVideo", {
              type: 5,
              freckleId: freckleId,
              freckleData: properties,
              layerId: this.selectLayer.key,
              layerData: this.selectLayer.data,
            });
          });
          this.autoSelect = false;
        }
      });
    },
    checkChange() {
      const nodes = this.$refs.treeLayer.getCheckedNodes();
      this.drawLayerPolygon(nodes.filter((i) => i.rootGeoserverUrl));
    },
    /**
     * 绘制图层图斑
     * @param arr
     */
    drawLayerPolygon(arr) {
      this.wmsLayersData = arr;
      if (arr.length < this.oldDrawLayer.length) {
        let hasLayer = false;
        for (const item of arr) {
          if (
            this.selectLayer?.polygonItem?.layerName?.includes(item.layerName)
          ) {
            hasLayer = true;
          }
        }
        if (!hasLayer) {
          this.clearCover();
          this.removeNumber();
        }
      }
      this.oldDrawLayer = arr;

      CommonMap.addVmsLayer(arr, this.mapId);
    },
    /**
     * 移除高亮polygon
     */
    clearCover() {
      if (this.selectPolygonLayer) {
        if (this.selectPolygonLayer.type === "circle") {
          //点
          clearCircle(this.mapRef, this.selectPolygonLayer.circleLayer);
        } else if (this.selectPolygonLayer.type === "line") {
          //线
          clearPolyline(this.mapRef, this.selectPolygonLayer.lineLayer);
        } else {
          //面
          this.mapRef.removeLayer(this.selectPolygonLayer.polygonLayer);
          this.selectPolygonLayer = null;
        }
      }
    },
    /**
     * 移除高亮
     */
    removeNumber() {
      if (this.numberInfoWindow) {
        this.mapRef.removeOverlay(this.numberInfoWindow);
        this.numberInfoWindow = null;
      }
    },
    /**
     * @description  : 地图点击回调事件
     * @param         { type } e
     * @return        { type }
     * @Date         : 2023-10-27 10:51:34
     * @Author       : Maws
     * @LastEditors  : Maws
     * @LastEditTime : Do not edit
     */
    mapClickGetPolygon(e) {
      let view = this.mapRef.getView();
      const viewResolution = view.getResolution();
      // 使用openlayers的vectorsource来生成bbox
      const wmsLayerObj = CommonMap.getWmsLayerAll(this.mapId);
      if (wmsLayerObj) {
        const url = wmsLayerObj?._layer
          ?.getSource()
          ?.getFeatureInfoUrl(e.coordinate, viewResolution, "EPSG:3857", {
            INFO_FORMAT: "application/json",
          });
        if (url) {
          let data = this.parseQueryParams(decodeURIComponent(url));

          let params = {
            workspace: "guotu",
            params: {
              request: "GetFeature",
              outputFormat: "application/json",
              QUERY_LAYERS: data.layers || data.LAYERS,
              ...data,
            },
          };
          return request({
            url: "/bdm/geo/queryWfs",
            method: "post",
            data: params,
          }).then((resp) => {
            console.log(resp);
            let filterResult = resp?.data?.features;
            if (filterResult && filterResult.length) {
              let feature = filterResult[0];
              console.log("feature", feature);
              this.HighlightPolygon(resp?.data, 1);
              this.showNumber(resp?.data, 1);
              const properties = feature.properties;
              this.$emit("mapToVideo", {
                type: 5,
                freckleId: properties.bsm,
                freckleData: properties,
                layerId: this.selectLayer.key,
                layerData: this.selectLayer.data,
              });
            } else {
              this.clearCover();
              this.removeNumber();
              this.$emit("mapToVideo", {
                type: 8,
              });
            }
          });
        }
      }
    },
    /**
     * 解析url参数为对象
     * @returns {{}}
     * @param url
     */
    parseQueryParams(url) {
      const urlParams = new URLSearchParams(url.split("?")[1] || "");
      const params = {};

      for (const [key, value] of urlParams.entries()) {
        params[key] = value;
      }

      return params;
    },
    /**
     * 高亮图斑
     * @param feature
     * @param is3857 null时 3857
     * @constructor
     */
    HighlightPolygon(feature, is3857) {
      this.clearCover();
      // 高亮地块

      if (
        feature?.features?.[0]?.geometry?.type?.toLowerCase().includes("line")
      ) {
        let coordinates = feature.features[0].geometry.coordinates;
        const lineType = feature?.features?.[0]?.geometry?.type;
        //线图层
        let lineLayer = describingPolyline(
          this.mapRef,
          coordinates,
          "rgba(223, 34, 24,0.8)",
          1,
          false,
          false,
          is3857,
          lineType
        );
        lineLayer.featureId = feature?.features?.[0].id;
        this.selectPolygonLayer = { lineLayer, type: "line" };
      } else if (
        feature?.features?.[0]?.geometry?.type?.toLowerCase().includes("point")
      ) {
        //点图层
        let coordinate = feature.features[0].geometry.coordinates;
        if (is3857) {
          coordinate = transCoordinate(coordinate, "EPSG:3857", "EPSG:4326");
        }

        let circleLayer = describingCircle2(this.mapRef, coordinate, 4, false, {
          fillColor: "rgba(223, 34, 24,0.4)",
          fillOpacity: 1,
          strokeColor: "rgba(223, 34, 24,0.8)",
          strokeWidth: 1,
        });
        circleLayer.featureId = feature?.features?.[0].id;
        this.selectPolygonLayer = { circleLayer, type: "circle" };
      } else {
        //面图层
        let style = new CTMapOl.style.Style({
          stroke: new CTMapOl.style.Stroke({
            color: "rgba(223, 34, 24,0.8)",
            width: 2,
          }),
          fill: new CTMapOl.style.Fill({
            color: "rgba(223, 34, 24,0.4)",
          }),
        });
        //flag为null时3857转4326
        let polygonFeature = new CTMapOl.format.GeoJSON().readFeatures(
          feature,
          {
            dataProjection: is3857 ? "EPSG:3857" : "EPSG:4326", // 当前元数据的投影坐标
            featureProjection: "EPSG:3857",
          }
        );
        let polygonLayer = new CTMapOl.layer.Vector({
          source: new CTMapOl.source.Vector({
            features: polygonFeature,
          }),
          className: "wms-polygon",
          style,
          zIndex: 103,
        });
        polygonLayer.featureId = feature?.features?.[0].id;
        this.mapRef.addLayer(polygonLayer);
        this.selectPolygonLayer = { polygonLayer, type: "polygon" };
      }
    },
    /**
     * 显示小旗子
     * @param feature
     * @param is3857 null时 3857
     */
    showNumber(feature, is3857) {
      let that = this;
      if (feature && !that.timer) {
        that.timer = setTimeout(() => {
          that.timer = null;
        }, 300);
        if (that.mapRef.getOverlayById("infoWindowId")) {
          closeInfoWindow(
            that.mapRef,
            that.mapRef.getOverlayById("infoWindowId")
          );
        }

        let textCenter;
        let featureProperties = feature.features[0].properties;
        let layerData;
        layerData = this.selectLayer.data;
        let BSMNum = this.getTbbh(layerData, featureProperties);
        let epsg = "4326";

        if (
          feature?.features?.[0]?.geometry?.type
            ?.toLowerCase()
            .includes("point")
        ) {
          //点
          textCenter = feature.features[0].geometry.coordinates;
          epsg = is3857 ? "3857" : "4326";
        } else {
          let maxList = [featureProperties.maxx, featureProperties.maxy];
          let minList = [featureProperties.minx, featureProperties.miny];

          let extent = [maxList[0], maxList[1], minList[0], minList[1]];
          textCenter = CTMapOl.extent.getCenter(extent);
        }
        that.numberInfoWindow = showTextPolygonId(
          this.mapRef,
          BSMNum,
          [textCenter],
          null,
          "overLayText",
          -5,
          0,
          epsg
        );
        that.timer = null;
      }
    },
    /**
     * 根据不同图层类型获取图斑编号
     * @param {*} layerData
     * @param {*} properties
     */
    getTbbh(layerData, properties) {
      let tbbh;
      let currentAbbreviation = layerData.abbreviation
        ? layerData.abbreviation
        : this.abbreviation;
      console.log("土地类型", { currentAbbreviation });
      // 添加图斑编号
      if (currentAbbreviation === "tdbp") {
        // 土地报批
        tbbh = properties.dkid ? properties.dkid : "";
      } else if (
        currentAbbreviation === "xztb" ||
        currentAbbreviation === "yjjbnt"
      ) {
        // 基本农田&土地利用现状
        tbbh = properties.tbbh ? properties.tbbh : "";
      } else if (currentAbbreviation === "stbhhx") {
        // 生态保护红线
        tbbh = properties.hxbm ? properties.hxbm : "";
      } else {
        tbbh = properties.bsm ? properties.bsm : "";
      }
      return tbbh;
    },
    /**
     * 查询图斑详细信息
     * @param layerId 图层id
     * @param freckleId 图斑id(bsm)
     * @param successFn
     */
    selectFeatureById(layerId, freckleId, successFn) {
      const params = {
        layerID: layerId,
        tbbhs: [freckleId],
        returnAllCols: true,
        returnGeometry: true,
      };
      getXjxlFeaturesByIds(params).then((resp) => {
        if (resp.code === 200 && resp.data?.geoData?.features?.length) {
          if (successFn) {
            successFn(resp);
          }
        }
      });
    },
    /**
     * 以地找视频带提示
     */
    findVideoByCoord(boolValue) {
      this.findVideoByCoordHandle(boolValue);
    },
    /**
     * 以地找视频
     */
    async findVideoByCoordHandle(boolValue, flag) {
      //flag表示是否是点击地图上的清除按钮
      if (boolValue && !flag) {
        await this.getPointsValid();
        if (!this.isEnableDraw) {
          return;
        }
      }
      if (boolValue && !flag) {
        this.doMessTs("点击开始绘制，右键撤销上一步绘制，双击结束绘制。");
      }
      this.isOpenFindVideByCoord = boolValue;
      this.clearDrawLayer();
      if (this.isOpenFindVideByCoord) {
        if (this.measureType !== "") {
          measure.setMeasureType("");
          this.measureType = "";
        }
        if (this.isOpenLookAtHere) {
          this.lookAthere(false);
        }

        // 开启找地
        this.mapRef.addInteraction(draw);
        this.mapRef.removeInteraction(doubleClickZoomArr[0]);
        draw.on("drawend", this.drawendFn);
        this.mapRef.on("contextmenu", (e) => {
          e.preventDefault();
          draw.removeLastPoint(); //移除上一个点
        });
        this.$emit("mapToVideo", {
          type: 7,
        });
      } else {
        // 结束找地
        this.mapRef.removeInteraction(draw);
        this.mapRef.addInteraction(doubleClickZoomArr[0]);
        draw.un("drawend", this.drawendFn);
        this.mapRef.un("contextmenu", (e) => {
          e.preventDefault();
        });
        this.$emit("mapToVideo", {
          type: 6,
        });
      }
    },
    /**
     * 以地找视频 drawend 事件
     * @param evt
     * @return {Promise<void>}
     */
    async drawendFn(evt) {
      const longlat = evt.feature.getGeometry().getCoordinates();
      let tmpLnglat = [[]];
      longlat[0].forEach((item) => {
        let tmp =
          CTMapOl.extend.formatLayer.transCooordinateFromOpenlayer(item);
        tmpLnglat[0].push(tmp);
      });
      let coordinates = tmpLnglat[0].slice(1);

      let center = getPolygonCenter(coordinates);
      this.turnCamera(center);
      let { vertexPercentList, centerPointPtz } =
        await this.getPercentPtzByCoord(center, tmpLnglat[0]);
      this.$emit("mapToVideo", {
        type: 1,
        polygonCenter: center,
        vertexPercentList,
        centerPointPtz,
      });
      setTimeout(() => {
        this.mapRef.removeInteraction(draw);
        this.mapRef.addInteraction(doubleClickZoomArr[0]);
      }, 500);
    },
    /**
     * 可视域开关
     * @param value
     */
    openViewShedChange(value) {
      this.isOpenViewshed = value;
      if (this.isOpenViewshed) {
        this.openVisibleInterval();
        this.LayeredClusterViewShed.setViewShedVisible(true);
      } else {
        this.closeVisibleInterval();
        this.LayeredClusterViewShed.setViewShedVisible(false);
      }
    },
    /**
     * 看这里开关
     * @param value
     */
    async lookAthere(value) {
      if (value) {
        await this.getPointsValid();
        if (!this.isEnableDraw) {
          return;
        }
      }
      this.isOpenLookAtHere = value;
      if (this.isOpenLookAtHere) {
        // this.findVideoByCoordHandle(false);// TODO:
        if (this.measureType === "area") {
          this.measureType = "";
          measure.setMeasureType("");
          return;
        }
        if (this.measureType === "distance") {
          this.measureType = "";
          measure.setMeasureType("");
          return;
        }
        if (lookPoint) {
          lookPoint.distory();
          lookPoint = null;
        }
        const pointStyle = new CTMapOl.style.Style({
          image: new CTMapOl.style.Icon({
            src: lookPointPng,
          }),
        });
        lookPoint = new pointClass(this.mapRef, pointStyle);
      } else {
        if (lookPoint) {
          lookPoint.distory();
          lookPoint = null;
        }
      }
    },
    /**
     * 看这里鼠标点击事件
     * @param evt
     * @return {Promise<void>}
     */
    async mapClickFn(evt) {
      if (this.isOpenLookAtHere) {
        if (lookPoint) {
          lookPoint.addPoint(evt.coordinate);
        }
        let tmp = CTMapOl.extend.formatLayer.transCooordinateFromOpenlayer(
          evt.coordinate
        );
        this.turnCamera(tmp);
      }
    },
    /**
     * 根据坐标转动可视域
     * @param lnglat
     */
    turnCamera(lnglat) {
      let params = {
        deviceCode: this.deviceCode,
        channelCode: this.channelCode,
        cameraLon: Number(this.longitude),
        cameraLat: Number(this.latitude),
        pointLon: lnglat[0],
        pointLat: lnglat[1],
        tenantId: this.isTenant,
        userId: this.userId,
      };
      turnToPtzByPointAngle(params).then((res) => {
        if (+res.code !== 200) {
          this.doMessTs(res.message || res.msg || "");
          this.getDeviceVisibleBySite();
        } else {
          console.log("摄像机转动自计算角度ptz：", res);
        }
      });
    },
    /**
     * 测距删除单个点返回
     * @param info 返回数据 coord 和 result
     */
    async measureOnReduce(info) {
      if (!this.measureClearOneFlag) {
        return false;
      }
      let { coordinates } = info;
      let lnglat = coordinates.map((item) => {
        return CTMapOl.extend.formatLayer.transCooordinateFromOpenlayer(item);
      });
      let center = getPolygonCenter(lnglat);
      this.turnCamera(center);
      let { vertexPercentList, centerPointPtz } =
        await this.getPercentPtzByCoord(center, lnglat);
      this.$emit("mapToVideo", {
        type: 2,
        vertexPercentList,
        centerPointPtz,
        vertexLngLats: lnglat,
      });
    },
    /**
     * 测距删除所有点返回
     */
    async measureOnRemove(reason) {
      this.measureClearOneFlag = false;
      if (reason === "reduce" || reason === "remove") {
        this.$emit("mapToVideo", {
          type: 6,
        });
        measure.clearMeasure();
        measure.onlyStartMeasure();
      }
    },
    /**
     * 测距测面完成返回
     * @param info 返回数据 coord 和 result
     */
    async measureOnFinish(info) {
      this.measureClearOneFlag = true;
      measure.stopMeasure();
      let { coordinates } = info;
      let lnglat = coordinates.map((item) => {
        return CTMapOl.extend.formatLayer.transCooordinateFromOpenlayer(item);
      });
      if (this.measureType === "distance") {
        let center = getPolygonCenter(lnglat);
        this.turnCamera(center);
        let { vertexPercentList, centerPointPtz } =
          await this.getPercentPtzByCoord(center, lnglat);
        this.$emit("mapToVideo", {
          type: 2,
          vertexPercentList,
          centerPointPtz,
          vertexLngLats: lnglat,
        });
      } else if (this.measureType === "area") {
        let coordinates = lnglat.slice(1);
        let center = getPolygonCenter(coordinates);
        this.turnCamera(center);
        let { vertexPercentList, centerPointPtz } =
          await this.getPercentPtzByCoord(center, lnglat);
        this.$emit("mapToVideo", {
          type: 3,
          vertexPercentList,
          centerPointPtz,
          vertexLngLats: lnglat,
        });
      }
    },
    /**
     * 测距
     */
    async ranging() {
      this.measureClearOneFlag = false;
      this.findVideoByCoordHandle(false);
      if (this.measureType === "distance") {
        this.measureType = "";
        measure.setMeasureType("");
        this.$emit("mapToVideo", {
          type: 6,
        });
        return;
      }
      if (this.isOpenLookAtHere) {
        this.lookAthere(false);
      }
      await this.getPointsValid();
      if (!this.isEnableDraw) {
        return;
      }
      this.doMessTs("点击开始绘制，右键撤销上一步绘制，双击结束绘制。");
      this.measureType = "distance";
      measure.setMeasureType("length");
      measure.startMeasure();
      this.$emit("mapToVideo", {
        type: 7,
      });
    },
    /**
     * 测面基
     */
    async areaMeasurement() {
      this.measureClearOneFlag = false;
      this.findVideoByCoordHandle(false);
      if (this.measureType === "area") {
        this.measureType = "";
        measure.setMeasureType("");
        this.$emit("mapToVideo", {
          type: 6,
        });
        return;
      }
      if (this.isOpenLookAtHere) {
        this.lookAthere(false);
      }
      await this.getPointsValid();
      if (!this.isEnableDraw) {
        return;
      }
      this.doMessTs("点击开始绘制，右键撤销上一步绘制，双击结束绘制。");
      this.measureType = "area";
      measure.setMeasureType("area");
      measure.startMeasure();
      this.$emit("mapToVideo", {
        type: 7,
      });
    },
    handleQieHuan() {
      this.$emit("update:main", this.main === 1 ? 2 : 1);
    },
    /**
     * 以地找视频清除绘制图层
     */
    clearDrawLayer() {
      let features = drawVectorLayer.getSource().getFeatures();
      features.forEach((item) => {
        drawVectorLayer.getSource().removeFeature(item);
      });
    },
    /**
     * 清除按钮
     */
    clearLayer(flag = false) {
      if (this.isOpenFindVideByCoord && !flag) {
        this.findVideoByCoordHandle(true, true);
      }
      this.measureClearOneFlag = false;
      // 清除视频联动以视频找地
      measureOverlay.removeByKey("videomap");
      measureOverlay.removeByKey("line1");
      measureOverlay.removeByKey("ploygon1");
      this.measureTipList = [];

      if (this.measureType === "distance") {
        measure.setMeasureType("length");
        measure.startMeasure();
      } else if (this.measureType === "area") {
        measure.setMeasureType("area");
        measure.startMeasure();
      } else {
        measure.setMeasureType("");
      }
      if (!flag) {
        this.$emit("mapToVideo", {
          type: 6,
        });
      }
      this.lnglatLocationClear(true);
    },
    handleBoxZoomClick(isZoomIn = !this.isZoomIn) {
      this.$emit("update:isZoomIn", isZoomIn);
      $("#mapDrag" + this.mapIndex).removeAttr("style");
    },
    locateToCamera() {
      if (this.isOpenViewshed && this.LayeredClusterViewShed) {
        setTimeout(() => {
          try {
            this.LayeredClusterViewShed.zoomToViewShed({ id: this.deviceCode });
          } catch (e) {
            console.log(e);
          }
        }, 500);
      } else {
        setZoomAndCenter(this.mapRef, this.longitude, this.latitude, 12);
      }
    },
    mapTypeChange() {
      if (this.mapType === "satellite") {
        this.mapType = "vector";
      } else {
        this.mapType = "satellite";
      }
      this.globalMap.changeTile(this.mapType);
    },
    /**
     * 获取百分比坐标
     * @param {*} center 中心点经纬度
     * @param {*} longlat 经纬度坐标
     */
    async getPercentPtzByCoord(center, longlat = []) {
      // 顶点百分比坐标
      let vertexPercentList = [];
      let centerPointPtz = {};
      try {
        let coords = [];
        if (longlat.length > 0) {
          coords = longlat.map((item) => ({
            pointLon: item[0],
            pointLat: item[1],
          }));
        }
        let params = {
          deviceCode: this.deviceCode,
          channelCode: this.channelCode,
          centerPoint: {
            //中心点经纬度
            pointLon: center[0], // 打点经度
            pointLat: center[1], // 打点纬度
          },
          vertexList: coords,
        };
        let res = await getPercentPtzByMassPointBatch(params);
        if (res.code === 200) {
          vertexPercentList = res.data.vertexPercentList;
          centerPointPtz = res.data.centerPointPtz;
        }
      } catch (error) {
        console.log(error);
      }
      return { vertexPercentList, centerPointPtz };
    },
    getDeivceIcon(deviceItem) {
      let arFlag = false; //是否显示ar设备
      let onlineFlag = false; //是否在线
      let offLineHasAr = false; //离线里有ar
      if (deviceItem.status === "0" || deviceItem.allLine === "0") {
        onlineFlag = true;
        if (String(deviceItem.categoryCode) === "2") {
          // 在线的ar设备
          arFlag = true;
        }
      } else {
        if (String(deviceItem.categoryCode) === "2") {
          // 在线的ar设备
          offLineHasAr = true;
        }
      }
      if (!onlineFlag && offLineHasAr) {
        //离线且离线的有ar设备
        arFlag = true;
      }
      this.isArCamera = arFlag;
      let icon = null;
      if (arFlag) {
        if (onlineFlag) {
          //ar在线
          icon = this.industryType.includes("g") ? arOnline_g : arOnline;
        } else {
          //ar离线
          icon = this.industryType.includes("g") ? arOffline_g : arOffline;
        }
      } else {
        if (onlineFlag) {
          //普通在线
          icon = this.industryType.includes("g") ? ipcOnline_g : ipcOnline;
        } else {
          //普通离线
          icon = this.industryType.includes("g") ? ipcOffline_g : ipcOffline;
        }
      }
      this.deviceIcon = icon;
    },
    doMessTs(text) {
      if (text) {
        this.$refs["ts"].doMessTs(text, true);
      }
    },
    async getPointsValid() {
      this.isEnableDraw = false;
      try {
        let params = {
          deviceCode: this.deviceCode,
        };
        let res = await pointsValid(params);
        if (res.code === 200) {
          this.isEnableDraw = true;
        } else {
          this.doMessTs("该摄像机暂未标定，请联系铁塔管理员。");
        }
      } catch (error) {
        this.doMessTs("该摄像机暂未标定，请联系铁塔管理员。");
        console.error(error);
      }
    },
    /**
     * 打开图层树
     */
    openLayerTree(show = !this.layerTree) {
      this.layerTree = show;
    },
    computeHeight() {
      let height = $("#mapDrag" + this.mapIndex).height();
      this.treeHeight = height * 0.79 + "px";
    },
  },
  beforeDestroy() {
    this.closeVisibleInterval();
    this.mapRef.removeInteraction(draw);
    measure.distoryMeasure();
    CommonMap.destroyWmsLayer(this.mapId);
    measure = null;
    draw = null;
    drawVectorSource = null;
    drawVectorLayer = null;
    this.mapRef = null;
    treeLayer = null;
    this.globalMap = null;
  },
};
</script>

<style lang="scss" scoped>
.bigScreen {
  width: 50%;
  height: 50%;
}

.minScreen {
  width: 38%;
  height: 38%;
}

.map-box-video {
  position: absolute;
  bottom: 0;
  right: 0;
  z-index: 9;
  max-width: 50%;
  max-height: 50%;
  min-width: 38%;
  min-height: 38%;
  -webkit-user-drag: none;

  .drag {
    width: 10px;
    height: 10px;
    overflow: hidden;
    position: absolute;
    left: 0;
    top: 0;
    z-index: 999;
    pointer-events: auto;
    &:hover {
      cursor: se-resize;
    }
  }
  .map-content {
    width: 100%;
    height: 100%;
  }

  .top-btn {
    position: absolute;
    top: 12px;
    left: 12px;
    display: flex;
    flex-direction: row;
    color: #ffffff;
    z-index: 2;

    .btn-li {
      width: 32px;
      height: 32px;
      background: rgba(0, 0, 0, 0.7);
      border-radius: 6px;
      display: flex;
      justify-content: center;
      align-items: center;
      margin-right: 5px;
      cursor: pointer;
      position: relative;
      &:last-child {
        margin-right: 0;
      }
      i {
        line-height: 1;
        font-size: 20px;
      }
    }
    .lnglat-location {
      position: absolute;
      left: 0;
      top: calc(100% + 6px);
      background: rgba(0, 0, 0, 0.7);
      border-radius: 4px;
      color: #fff;
      font-size: 14px;
      padding: 12px;
      cursor: default;
      width: 318px;
      overflow: auto;
      &.large {
        width: 390px;
      }
      .ttag {
        position: relative;
        display: flex;
        align-items: center;
        .radio {
          display: flex;
          align-items: center;
          color: #fff;
          margin-right: 24px;
          cursor: pointer;
          b {
            display: block;
            width: 16px;
            height: 16px;
            border: 1px solid #fff;
            border-radius: 50%;
            margin-right: 6px;
          }
          &.on {
            b {
              border: 5px solid #909399;
              background: #fff;
            }
          }
        }
        .lnglatLocation-down {
          position: absolute;
          font-size: 14px;
          color: #fff;
          right: 0;
          top: 50%;
          transform: translateY(-50%);
          cursor: pointer;
          &.down {
            transform: translateY(-50%) rotate(180deg);
            transform-origin: 50% 50%;
          }
        }
      }
      .ccon {
        margin-top: 12px;
        .it {
          margin-bottom: 12px;
          display: flex;
          align-items: center;
          &:last-child {
            margin: 0;
          }
          > span {
            color: #fff;
            margin-right: 12px;
            white-space: nowrap;
          }
          .input {
            flex: 1;
            height: 32px;
            margin-right: 12px;
            &:last-of-type {
              margin: 0;
            }
            input {
              display: block;
              width: 100%;
              height: 100%;
              border: 1px solid transparent;
              border-radius: 4px;
              outline: none;
              background: none;
              font-size: 14px;
              color: #fff;
              padding: 0 11px;
              background: rgba(255, 255, 255, 0.2);
              &::placeholder {
                color: rgba(255, 255, 255, 0.7);
              }
            }
            &.error {
              input {
                border-color: #ed5158;
              }
            }
          }
          > i {
            font-size: 24px;
            line-height: 1;
            margin-left: 12px;
            cursor: pointer;
            &:hover {
              opacity: 0.6;
            }
            &:active {
              opacity: 0.8;
            }
            &.unable {
              opacity: 0.4;
              cursor: not-allowed;
            }
          }
        }
      }
      .tts {
        margin: 12px 0 0 0;
        background: rgba(237, 81, 88, 0.2);
        border-radius: 4px;
        color: #ed5158;
        line-height: 20px;
        position: relative;
        padding: 6px 0 6px 36px;
        &:before {
          content: "\eb83";
          font-family: iconfont;
          width: 18px;
          height: 18px;
          line-height: 18px;
          text-align: center;
          position: absolute;
          left: 12px;
          top: 50%;
          font-size: 16px;
          transform: translateY(-50%);
        }
        span {
          display: block;
          font-size: 14px;
        }
      }
      .bbtn {
        display: flex;
        justify-content: center;
        margin-top: 12px;
        span {
          display: block;
          width: 108px;
          height: 32px;
          line-height: 32px;
          background: rgba(255, 255, 255, 0.2);
          border-radius: 4px;
          font-size: 14px;
          color: #fff;
          margin: 0 6px;
          text-align: center;
          cursor: pointer;
          &.on {
            background: rgba(255, 255, 255, 0.4);
          }
          &:hover {
            opacity: 0.6;
          }
          &:active {
            opacity: 0.8;
          }
        }
      }
    }
  }
  .map-level {
    width: 24px;
    position: absolute;
    bottom: 8px;
    left: 6px;
    z-index: 1;
    background: #ffffff;
    box-shadow: 0px 2px 5px 0px rgba(168, 175, 184, 0.54);
    border-radius: 4px;
    text-align: center;
    padding: 2px 0;
    span {
      color: #172537;
      font-size: 12px;
    }
    i {
      color: #000;
      display: block;
      height: 18px;
      line-height: 18px;
      font-size: 14px;
      font-weight: bold;
      cursor: pointer;
      &.unable {
        opacity: 0.4;
        cursor: not-allowed;
      }
    }
  }
  .right-btn {
    position: absolute;
    width: 24px;
    display: flex;
    flex-direction: column;
    bottom: 8px;
    right: 8px;
    color: #000;
    z-index: 1;
    .map-level {
      position: static;
      margin-bottom: 4px;
    }
    .rbtn-li {
      width: 24px;
      height: 24px;
      margin-bottom: 4px;
      background: #ffffff;
      box-shadow: 0 2px 2px 0 rgba(168, 175, 184, 0.3),
        0 2px 6px 0 rgba(161, 176, 195, 0.7);
      border-radius: 4px;
      display: flex;
      justify-content: center;
      align-items: center;
      cursor: pointer;

      &:last-child {
        margin-bottom: 0;
      }

      .qie-huan {
        width: 100%;
        height: 100%;
        display: flex;
        align-items: center;
        justify-content: center;
        transform: rotateZ(45deg);
      }
      i {
        line-height: 1;
        font-size: 18px;
      }
    }
  }
  ::-webkit-scrollbar-thumb {
    background-color: rgba(255, 255, 255, 0.4) !important;
    &:hover {
      background-color: rgba(255, 255, 255, 0.55) !important;
    }
  }
  .el-scrollbar__bar {
    .el-scrollbar__thumb {
      background-color: rgba(255, 255, 255, 0.4) !important;
      &:hover {
        background-color: rgba(255, 255, 255, 0.55) !important;
      }
    }
  }
}

.measure-over-tip {
  padding: 2px 5px;
  background: hsla(0, 0%, 9%, 0.8);
  border-radius: 4px;
  color: #ccc;
  display: -webkit-box;
  display: -ms-flexbox;
  display: flex;
  font-size: 13px;
  width: auto;
  height: auto;

  &::before {
    border-left: 6px solid transparent;
    border-right: 6px solid transparent;
    border-top: 6px solid hsla(0, 0%, 9%, 0.8);
    bottom: -5px;
    content: "";
    left: 50%;
    margin-left: -6px;
    position: absolute;
  }
}
.ts {
  margin-top: 22px;
}
/deep/ .layer-tree-popover {
  min-height: 100px;
  padding: 0 !important;
  background: rgba(0, 0, 0, 0.7) !important;
  border: none !important;
  margin-top: 6px !important;
  position: absolute !important;
  left: 0 !important;
  top: 100% !important;
  overflow: hidden;

  .el-tree {
    overflow-y: auto;
    background: transparent;
    color: #fff;

    .el-tree-node:focus > .el-tree-node__content {
      background: transparent !important;
    }
    .el-tree-node .el-tree-node__content {
      padding-left: 0 !important;
      height: 32px;
    }
    .el-tree-node .el-tree-node__content:hover {
      background: rgba(255, 255, 255, 0.2) !important;
    }

    .el-tree-node__content > label.el-checkbox {
      display: none;
    }

    .el-tree-node__expand-icon {
      color: #fff !important;
      width: 20px;
      height: 20px;
      padding: 0;
      text-align: center;
      line-height: 20px;
      margin: 0 6px;
      pointer-events: none;
    }
    .el-tree-node__label {
      font-size: 14px;
      position: relative;
      color: #fff !important;
    }
    &::-webkit-scrollbar-thumb {
      background-color: rgba(255, 255, 255, 0.4) !important;
      &:hover {
        background-color: rgba(255, 255, 255, 0.55) !important;
      }
    }
  }

  .is-leaf {
    width: 16px !important;
    height: 16px !important;
    margin-left: 12px !important;
    &::before {
      content: "";
      display: block;
      width: 16px;
      height: 16px;
      border: 1px solid #ffffff;
      border-radius: 50%;
    }
  }
  .is-checked {
    .is-leaf {
      &::before {
        background: #ffffff;
        border: 5px solid #909399;
      }
    }
  }
}
</style>
